package com.emip.job.method;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.emip.bean.AlterLogBean;
import com.emip.bean.HourStoreBean;
import com.emip.bean.ItemBean;
import com.emip.bean.SecondStoreBean;
import com.emip.bean.SiteBean;
import com.emip.bean.SiteItemBean;
import com.emip.bean.Store;
import com.emip.service.HourStoreService;
import com.emip.service.ItemService;
import com.emip.service.SecondStoreService;
import com.emip.service.SiteService;
import com.emip.util.ReportFormat;
import com.emip.util.report.Comput;
import com.emip.util.report.Statistics;

@Component
public class HourMethod {

	static Logger logger = Logger.getLogger(HourMethod.class);
	
	@Autowired
	SecondStoreService secondStoreService;
	
	@Autowired
	HourStoreService hourStoreService;
	
	@Autowired
	ItemService itemService;
	
	@Autowired
	SiteService siteService;

	public void doWork2(Calendar clone, Statistics statistic) {
		SimpleDateFormat sf = new SimpleDateFormat(ReportFormat.HOURFORMAT);
		List<SiteItemBean> siteItems = statistic.getSiteItems();
		for (int i = 0; i < siteItems.size(); i++) {
			SiteItemBean siteItem = siteItems.get(i);
			String itemId = siteItem.getItem().getId();
			String siteId = siteItem.getSite().getId();
			Date lastDate = hourStoreService.getLastDate(itemId, siteId);
			Calendar calendar = Calendar.getInstance();
			Calendar preDate = Calendar.getInstance();
			preDate.add(Calendar.HOUR, -1);
			preDate.set(Calendar.MINUTE, 59);
			preDate.set(Calendar.SECOND, 59);
			if (lastDate != null) {
				calendar.setTime(lastDate);
				calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
			} else {
				calendar = preDate;
			}

			List<Object> normal = 
				secondStoreService.getNormalStat(
					sf.format(calendar.getTime()) + ":00:00",
					sf.format(preDate.getTime()) + ":59:59", itemId, siteId);

			List<Object> all = 
				secondStoreService.getStat(
					sf.format(calendar.getTime()) + ":00:00",
					sf.format(preDate.getTime()) + ":59:59", itemId, siteId);
			
			int index = 0, normalIndex = 0;
			while (calendar.getTimeInMillis() <= clone.getTimeInMillis()) {
				Date time = calendar.getTime();
				String date = sf.format(time);
				HourStoreBean hour = hourStoreService.findByHour(date, siteId, itemId);
				if (hour == null) {
					hour = new HourStoreBean();
					hour.setGenTime(time);
						
					SiteBean site = siteService.getSiteByID(siteId);
					hour.setSite(site);

					ItemBean item = itemService.getItemByID(itemId);
					hour.setItem(item);
						
					if (item == null || site == null) continue;
				}

				hour.setFlag(Statistics.EXCEPTION_FLAG);
				if (index < all.size()) {
					Object[] results = (Object[]) all.get(index);
					if (results[results.length - 1].equals(date)) {
						index++;

						if (normalIndex < normal.size()) {
							Object[] normalResults = (Object[]) normal.get(normalIndex);
							if (normalResults[normalResults.length - 1].equals(date)) {
								if (normalResults[3] > 0) {
									hour.setValue((Double) normalResults[2]);
									hour.setFlag(null);
								}
								else {
									hour.setValue((Double) results[2]);
								}
								normalIndex++;
							}
							else {
								hour.setValue((Double) results[2]);
							}
						}
					}
				}

				hourStoreService.merge(hour);
			}
		}
	}

	public Store comput(Calendar calendar, Statistics statistic, String itemId, String siteId) {
		SimpleDateFormat sf = new SimpleDateFormat(ReportFormat.HOURFORMAT);
		Calendar cal = (Calendar) calendar.clone();
		cal.add(Calendar.HOUR, -1);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		Date startDate = cal.getTime();
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
		Date endDate = cal.getTime();
		String[] results = secondStoreService.getStatistics(startDate, endDate, itemId, siteId);

		//注意每个计算的位置
		HourStoreBean hour = hourStoreService.findByHour(sf.format(startDate), siteId, itemId);
		if (hour == null) {
			hour = new HourStoreBean();
			hour.setGenTime(endDate);
				
			SiteBean site = siteService.getSiteByID(siteId);
			hour.setSite(site);

			ItemBean item = itemService.getItemByID(itemId);
			hour.setItem(item);
				
			if (item == null || site == null) continue;
		}
		if (results == null || results[3] == 0) {
			hour.setFlag(Statistics.EXCEPTION_FLAG);
		}
		if (results != null) hour.setValue((Double) results[2]);

		hourStoreService.merge(hour);
	}
	
	public Store comput(Calendar calendar, Statistics statistic, String[] items, String siteId) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(ReportFormat.SECONDFORMAT);
		Calendar cal = (Calendar) calendar.clone();
		cal.add(Calendar.HOUR, -1);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		Date startDate = cal.getTime();
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
		Date endDate = cal.getTime();
		List<SecondStoreBean> seconds = secondStoreService.getByTimespan(
				dateFormat.format(startDate), dateFormat.format(endDate), items, siteId);
		
		//如果没有数据则返回
		if (seconds == null || seconds.size() == 0) return null;
		
		logger.info("Report Job, Computing HOUR Datawith siteId=" + 
				siteId + " and itemId=" + Arrays.toString(items) + ":" + 
				dateFormat.format(startDate) + "  --  " +
				dateFormat.format(endDate));
		
		statistic.init();
//		update(statistic.comput(seconds));
		statistic.comput(seconds);
		Map<String, Comput> computs = statistic.getResults();
		SimpleDateFormat sf = new SimpleDateFormat(ReportFormat.HOURFORMAT);
		HourStoreBean hour = null;
		for (Map.Entry<String, Comput> entry: computs.entrySet()) {
			Comput comput = entry.getValue();
			String[] key = entry.getKey().split("_");
			if (!key[0].equals("AverageComput")) continue;
			hour = hourStoreService.findByHour(sf.format(endDate), key[1], key[2]);
			if (hour == null) {
				hour = new HourStoreBean();
				hour.setGenTime(endDate);
				
				SiteBean site = siteService.getSiteByID(key[1]);
				hour.setSite(site);

				ItemBean item = itemService.getItemByID(key[2]);
				hour.setItem(item);
				
				if (item == null || site == null) continue;
			}
			hour.setFlag(comput.getFlag());
			String result = null;
			try {
				result = comput.getResult();
			} catch (Exception e) {
				continue;
			}
			if (result == null || comput.getCount() == 0) continue;
			hour.setValue(result);

			SiteBean site = siteService.getSiteByID(key[1]);
			hour.setSite(site);
			
			ItemBean item = itemService.getItemByID(key[2]);
			hour.setItem(item);
			
			if (item == null || site == null) continue;
			hourStoreService.merge(hour);
		}
		return hour;
	}

	public void doWork(Calendar clone, Statistics statistic) {
		List<SiteItemBean> siteItems = statistic.getSiteItems();
		for (int i = 0; i < siteItems.size(); i++) {
			SiteItemBean siteItem = siteItems.get(i);
			String itemId = siteItem.getItem().getId();
			String siteId = siteItem.getSite().getId();
			Date lastDate = hourStoreService.getLastDate(itemId, siteId);
			if (lastDate != null) {
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(lastDate);
				calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
				while (calendar.getTimeInMillis() <= clone.getTimeInMillis()) {
					calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
					
					//判断当天是否有数据，没有数据则跳过
					if (calendar.get(Calendar.HOUR_OF_DAY) == 0) {
						SimpleDateFormat dateFormat = new SimpleDateFormat(ReportFormat.DAYFORMAT);
						String date = dateFormat.format(calendar.getTime());
						long size = secondStoreService.getCount(date, new String[]{itemId}, siteId);
						if (size == 0) {
							System.out.println("No Data @  " + date);
							calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1);
							calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 1);
							continue;
						}
					}
					
					comput(calendar, statistic, new String[]{itemId}, siteId);
				}
			} else {
				comput(clone, statistic, new String[]{itemId}, siteId);
			}
		}
	}
	
	public void statistic(Calendar clone, Statistics statistic, String itemId, String siteId) {
		comput(clone, statistic, new String[]{itemId}, siteId);
	}
	
	public void merge(AlterLogBean log) {
		String siteId = log.getSite().getId();
		String itemId = log.getItem().getId();
		String date = log.getDate();
		SimpleDateFormat sf = new SimpleDateFormat(ReportFormat.HOURFORMAT);
		HourStoreBean store = 
				hourStoreService.findByHour(sf.format(date), siteId, itemId);
		store.setValue(log.getNewvalue());
		hourStoreService.merge(store);
	}
}
